home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
term-source.lha
/
Extras
/
Source
/
term-Source.lha
/
termRaster.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-07
|
8KB
|
459 lines
/*
** termRaster.c
**
** Screen character (raster) buffering routines
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* DeleteRaster():
*
* Free the contents of the character raster.
*/
VOID
DeleteRaster()
{
if(RasterSemaphore)
{
FreeVecPooled(RasterSemaphore);
RasterSemaphore = NULL;
}
if(Raster)
{
FreeVecPooled(Raster);
Raster = NULL;
}
if(RasterAttr)
{
FreeVecPooled(RasterAttr);
RasterAttr = NULL;
}
}
/* CreateRaster():
*
* Create the character raster.
*/
BYTE
CreateRaster()
{
/* Width of the screen * 2 (in characters),
* extra for double width. The window size
* may change, the screen size hopefully
* doesn't.
*/
RasterWidth = (Window -> WScreen -> Width / TextFontWidth) * 2;
/* Height of the character raster. */
RasterHeight = Window -> WScreen -> Height / TextFontHeight;
/* Allocate the raster. */
if(Raster = (STRPTR)AllocVecPooled(RasterWidth * RasterHeight,MEMF_ANY | MEMF_CLEAR))
{
/* Allocate the raster attributes. */
if(RasterAttr = (STRPTR)AllocVecPooled(RasterHeight,MEMF_ANY | MEMF_CLEAR))
{
if(RasterSemaphore = (struct SignalSemaphore *)AllocVecPooled(sizeof(struct SignalSemaphore),MEMF_ANY))
{
InitSemaphore(RasterSemaphore);
return(TRUE);
}
}
}
DeleteRaster();
return(FALSE);
}
/* RasterEraseScreen(BYTE Mode):
*
* Erase parts of the screen.
*/
VOID __regargs
RasterEraseScreen(BYTE Mode)
{
LONG First,
Last;
ObtainSemaphore(RasterSemaphore);
switch(Mode)
{
case 1: First = 0;
Last = CursorY * RasterWidth + CursorX + 1;
memset(RasterAttr,SCALE_NORMAL,CursorY + 1);
break;
case 2: First = 0;
Last = RasterHeight * RasterWidth - 1;
memset(RasterAttr,SCALE_NORMAL,RasterHeight);
break;
default:First = CursorY * RasterWidth + CursorX;
Last = RasterHeight * RasterWidth - 1;
memset(&RasterAttr[CursorY],SCALE_NORMAL,RasterHeight - CursorY);
break;
}
RethinkRasterLimit();
if(Last > First)
memset(&Raster[First],' ',Last - First);
ConFontScaleUpdate();
ReleaseSemaphore(RasterSemaphore);
}
/* RasterEraseLine(BYTE Mode):
*
* Erase parts of the current cursor line.
*/
VOID __regargs
RasterEraseLine(BYTE Mode)
{
LONG First,
Last;
ObtainSemaphore(RasterSemaphore);
switch(Mode)
{
/* From beginning to current cursor position. */
case 1: First = CursorY * RasterWidth;
Last = First + CursorX + 1;
break;
/* Entire line. */
case 2: First = CursorY * RasterWidth;
Last = First + RasterWidth - 1;
break;
/* From current cursor position towards end. */
default:First = CursorY * RasterWidth + CursorX;
Last = (CursorY + 1) * RasterWidth - 1;
break;
}
if(Last > First)
memset(&Raster[First],' ',Last - First);
ReleaseSemaphore(RasterSemaphore);
}
/* RasterEraseCharacters(WORD Chars):
*
* Erase a number of characters in the current cursor
* line.
*/
VOID __regargs
RasterEraseCharacters(WORD Chars)
{
if(CursorX < RasterWidth - 1)
{
LONG First,
Diff;
UBYTE *To,
*From;
ObtainSemaphore(RasterSemaphore);
First = CursorY * RasterWidth + CursorX;
To = &Raster[First];
if(CursorX + Chars >= RasterWidth)
{
Diff = RasterWidth - 1 - CursorX;
while(Diff-- > 0)
*To++ = ' ';
}
else
{
From = &Raster[First + Chars];
Diff = RasterWidth - (CursorX + 1 + Chars);
while(Diff--)
{
*To++ = *From;
*From++ = ' ';
}
}
ReleaseSemaphore(RasterSemaphore);
}
}
/* RasterClearLine(WORD Lines):
*
* Clear and remove a number of lines.
*/
VOID __regargs
RasterClearLine(WORD Lines,WORD Top)
{
if(Lines)
{
LONG RegionBottom;
ObtainSemaphore(RasterSemaphore);
if(RegionSet)
RegionBottom = Bottom;
else
RegionBottom = LastLine + 1;
if(Top + Lines >= RegionBottom)
RasterEraseScreen(0);
else
{
LONG Max;
UBYTE *From,
*To;
Max = (RegionBottom - (Top + Lines)) * RasterWidth;
From = &Raster[(Top + Lines) * RasterWidth];
To = &Raster[ Top * RasterWidth];
while(Max--)
{
*To++ = *From;
*From++ = ' ';
}
memset(&RasterAttr[RegionBottom - Lines],SCALE_NORMAL,Lines);
}
RethinkRasterLimit();
ConFontScaleUpdate();
ReleaseSemaphore(RasterSemaphore);
}
}
/* RasterInsertLine(WORD Lines):
*
* Insert a number of lines at the current cursor line.
*/
VOID __regargs
RasterInsertLine(WORD Lines,WORD Top)
{
if(Lines)
{
LONG RegionBottom;
if(RegionSet)
RegionBottom = Bottom;
else
RegionBottom = LastLine + 1;
if(Top + Lines > RegionBottom)
RasterEraseScreen(0);
else
{
LONG From,To,
Max;
UBYTE *FromPtr,
*ToPtr;
ObtainSemaphore(RasterSemaphore);
Max = (RegionBottom - Lines - Top) * RasterWidth;
From = (RegionBottom - Lines) * RasterWidth - 1;
To = RegionBottom * RasterWidth - 1;
FromPtr = &Raster[From];
ToPtr = &Raster[To];
while(Max--)
*ToPtr-- = *FromPtr--;
memset(&Raster[Top * RasterWidth],' ',Lines * RasterWidth);
ReleaseSemaphore(RasterSemaphore);
}
}
}
/* RasterScrollRegion(WORD Direction,WORD RasterTop,WORD RasterBottom,WORD RasterLines):
*
* Scroll the contents of the character raster up/down.
*/
VOID __regargs
RasterScrollRegion(WORD Direction,WORD RasterTop,WORD RasterBottom,WORD RasterLines)
{
WORD Dir = ABS(Direction);
ObtainSemaphore(RasterSemaphore);
if(Dir >= RasterLines)
{
/* All that is needed is to delete the lines. */
memset(&Raster[RasterTop * RasterWidth],' ',RasterLines * RasterWidth);
}
else
{
LONG First,
Last,
Max,
i;
UBYTE *From,
*To;
Max = (RasterLines - Dir) * RasterWidth;
if(Direction < 0)
{
First = (RasterTop + RasterLines - Dir) * RasterWidth - 1;
Last = (RasterTop + RasterLines ) * RasterWidth - 1;
From = &Raster[First];
To = &Raster[Last];
while(Max--)
*To-- = *From--;
for(i = RasterBottom ; i >= (RasterTop + Dir) ; i--)
RasterAttr[i] = RasterAttr[i - Dir];
memset(&Raster[RasterTop * RasterWidth],' ',RasterWidth * Dir);
memset(&RasterAttr[RasterTop],SCALE_NORMAL,Dir);
}
else
{
First = RasterTop * RasterWidth + RasterWidth * Dir;
Last = RasterTop * RasterWidth;
From = &Raster[First];
To = &Raster[Last];
while(Max--)
*To++ = *From++;
memset(&Raster[(RasterBottom - Dir) * RasterWidth],' ',RasterWidth * Dir);
for(i = RasterTop ; i <= (RasterBottom - Dir) ; i++)
RasterAttr[i] = RasterAttr[i + Dir];
memset(&RasterAttr[RasterBottom - Dir],SCALE_NORMAL,Dir);
}
}
RethinkRasterLimit();
ConFontScaleUpdate();
ReleaseSemaphore(RasterSemaphore);
}
/* RasterShiftChar(WORD Size):
*
* Shift the characters following the current cursor
* position Size characters to the right.
*/
VOID __regargs
RasterShiftChar(WORD Size)
{
LONG i,
First;
UBYTE *From,
*To;
ObtainSemaphore(RasterSemaphore);
if(CursorX + Size >= RasterWidth - 1)
{
i = RasterWidth - 1 - CursorX;
To = &Raster[CursorY * RasterWidth + CursorX];
while(i-- > 0)
*To++ = ' ';
}
else
{
First = (CursorY + 1) * RasterWidth - 1;
To = &Raster[First];
From = &Raster[First - Size];
i = RasterWidth - Size;
while(i-- > CursorX)
*To-- = *From--;
To = &Raster[CursorY * RasterWidth + CursorX];
while(Size--)
*To++ = ' ';
}
ReleaseSemaphore(RasterSemaphore);
}
/* RasterPutString(STRPTR String,WORD Length):
*
* Put a string into the character raster.
*/
VOID __regargs
RasterPutString(STRPTR String,WORD Length)
{
ObtainSemaphore(RasterSemaphore);
if(Length == 1)
{
if(CursorX + 1 < RasterWidth)
Raster[CursorY * RasterWidth + CursorX] = String[0];
}
else
{
if(CursorX + Length >= RasterWidth)
Length = RasterWidth - 1 - CursorX;
if(Length > 0)
memcpy(&Raster[CursorY * RasterWidth + CursorX],String,Length);
}
ReleaseSemaphore(RasterSemaphore);
}